package com.hzncc.flowable_diboot.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.binding.Binder;
import com.diboot.core.binding.QueryBuilder;
import com.diboot.core.service.DictionaryService;
import com.diboot.core.service.impl.BaseServiceImpl;
import com.diboot.core.util.S;
import com.diboot.core.vo.LabelValue;
import com.diboot.core.vo.Pagination;
import com.hzncc.flowable_diboot.contract.entity.SalesContract;
import com.hzncc.flowable_diboot.custom_field.CustomFieldUtil;
import com.hzncc.flowable_diboot.custom_field.entity.CustomTableItemConfig;
import com.hzncc.flowable_diboot.custom_field.exception.CustomTableException;
import com.hzncc.flowable_diboot.custom_field.service.CustomTableConfigService;
import com.hzncc.flowable_diboot.custom_field.vo.CustomTableConfigDetailVO;
import com.hzncc.flowable_diboot.custom_field.vo.CustomTableItemConfigListVO;
import com.hzncc.flowable_diboot.entity.contract.ContractProgress;
import com.hzncc.flowable_diboot.mapper.ContractProgressMapper;
import com.hzncc.flowable_diboot.mapper.SalesContractMapper;
import com.hzncc.flowable_diboot.util.WordUtils;
import com.hzncc.flowable_diboot.vo.contract.ContractProgressListVO;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ContractProgressService extends BaseServiceImpl<ContractProgressMapper, ContractProgress> {

    private final SalesContractMapper salesContractMapper;
    private final CustomTableConfigService customTableConfigService;
    private final DictionaryService dictionaryService;

    public List<ContractProgressListVO> getList(ContractProgress queryDto, Pagination pagination) {
        if (queryDto == null) {
            queryDto = new ContractProgress();
        }
        QueryWrapper<ContractProgress> queryWrapper = QueryBuilder.toQueryWrapper(queryDto);
        queryWrapper.orderByDesc("create_time");
        List<ContractProgress> entityList = this.getEntityList(queryWrapper, pagination);
        // 合同进度为空
        if (entityList == null || entityList.isEmpty()) {
            return Collections.emptyList();
        }
        List<LabelValue> paymentMethod = dictionaryService.getLabelValueList("paymentMethod");
        Map<Object,String> paymentMethodMap = paymentMethod.stream().collect(Collectors.toMap(LabelValue::getValue, LabelValue::getLabel));
        List<LabelValue> projectContractPayMethod = dictionaryService.getLabelValueList("projectContractPayMethod");
        Map<Object,String> projectContractPayMethodMap = projectContractPayMethod.stream().collect(Collectors.toMap(LabelValue::getValue, LabelValue::getLabel));
        List<ContractProgressListVO> contractProgressListVOS = Binder.convertAndBindRelations(entityList, ContractProgressListVO.class);
        for (ContractProgressListVO contractProgressListVO : contractProgressListVOS) {
            List<SalesContract> salesContracts = salesContractMapper.selectListByContractId(contractProgressListVO.getId());
            contractProgressListVO.setOrderModel(salesContracts.stream().map(SalesContract::getOrderModel).collect(Collectors.joining(",")));
            contractProgressListVO.setMachineTools(salesContracts.stream().map(SalesContract::getOrderItem).collect(Collectors.joining(",")));
            // 合同总金额
            String totalAmount = StrUtil.nullToDefault(contractProgressListVO.getTotalAmount(), "0.00");
            // 已收款金额
            String receivedAmount = StrUtil.nullToDefault(contractProgressListVO.getReceivedAmount(), "0.00");
            BigDecimal totalAmountBigDecimal = new BigDecimal(totalAmount);
            BigDecimal receivedAmountBigDecimal = new BigDecimal(receivedAmount);
            if (totalAmountBigDecimal.compareTo(BigDecimal.ZERO) != 0) {
                contractProgressListVO.setPayProgress(receivedAmountBigDecimal.divide(totalAmountBigDecimal, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP).toPlainString() + "%");
            }
            if (S.equals(contractProgressListVO.getContractCate(),"系统类") && contractProgressListVO.getSettlementMethod() != null){
                contractProgressListVO.setSettlementMethodLabel(paymentMethodMap.get(contractProgressListVO.getSettlementMethod()));
            }else if (S.equals(contractProgressListVO.getContractCate(),"项目类") || S.equals(contractProgressListVO.getContractCate(),"其他类") && contractProgressListVO.getSettlementMethod() != null){
                contractProgressListVO.setSettlementMethodLabel(projectContractPayMethodMap.get(contractProgressListVO.getSettlementMethod()));
            }
        }
        return contractProgressListVOS;
    }

    public File exportFile(ContractProgress queryDto) throws IOException {
        if (queryDto == null) {
            queryDto = new ContractProgress();
        }
        QueryWrapper<ContractProgress> queryWrapper = QueryBuilder.toQueryWrapper(queryDto);
        queryWrapper.orderByDesc("create_time");
        List<ContractProgress> entityList = this.getEntityList(queryWrapper);
        List<ContractProgressListVO> contractProgressListVOS = Binder.convertAndBindRelations(entityList, ContractProgressListVO.class);
        for (ContractProgressListVO contractProgressListVO : contractProgressListVOS) {
            List<SalesContract> salesContracts = salesContractMapper.selectListByContractId(contractProgressListVO.getId());
            contractProgressListVO.setOrderModel(salesContracts.stream().map(SalesContract::getOrderModel).collect(Collectors.joining(",")));
            contractProgressListVO.setMachineTools(salesContracts.stream().map(SalesContract::getOrderItem).collect(Collectors.joining(",")));
            // 合同总金额
            String totalAmount = StrUtil.nullToDefault(contractProgressListVO.getTotalAmount(), "0.00");
            // 已收款金额
            String receivedAmount = StrUtil.nullToDefault(contractProgressListVO.getReceivedAmount(), "0.00");
            BigDecimal totalAmountBigDecimal = new BigDecimal(totalAmount);
            BigDecimal receivedAmountBigDecimal = new BigDecimal(receivedAmount);
            if (totalAmountBigDecimal.compareTo(BigDecimal.ZERO) != 0) {
                contractProgressListVO.setPayProgress(receivedAmountBigDecimal.divide(totalAmountBigDecimal, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP).toPlainString() + "%");
            }
        }

        return createExcelFile(contractProgressListVOS);
    }

    private File createExcelFile(List<ContractProgressListVO> contractProgressListVOS) throws IOException {
        // 获取配置
        CustomTableConfigDetailVO userConfig = customTableConfigService.getConfig("contract-progress");
        // 创建工作簿
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet(S.isNotBlank(userConfig.getName()) ? userConfig.getName() : "sheet1");

            // 获取导出字段
            List<CustomTableItemConfigListVO> tableItemConfigs = userConfig.getTableItemConfigs().stream()
                    .filter(CustomTableItemConfig::getExportable).sorted(Comparator.comparingInt(CustomTableItemConfig::getSort)).toList();
            // 创建表头
            Row headerRow = sheet.createRow(0);
            CellStyle headerStyle = workbook.createCellStyle();
            Font font = workbook.createFont();
            font.setBold(true); // 设置字体加粗
            font.setFontHeightInPoints((short) 14); // 设置字体大小
            headerStyle.setFont(font);
            headerStyle.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); // 设置背景颜色
            headerStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中对齐
            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中对齐
            // 获取表头
            List<String> headers = tableItemConfigs.stream().map(CustomTableItemConfig::getFieldLabel).toList();
            for (int i = 0; i < headers.size(); i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers.get(i));
                sheet.setColumnWidth(i, headers.get(i).length() * 4 * 256);
                cell.setCellStyle(headerStyle);
            }

            // 填充数据
            int rowNum = 1;
            // 获取字段名
            List<String> fieldNames = tableItemConfigs.stream().map(CustomTableItemConfig::getFieldName).toList();
            for (Object datum : contractProgressListVOS) {
                Row row = sheet.createRow(rowNum++);
                for (int i = 0; i < fieldNames.size(); i++) {
                    Object fieldValue = CustomFieldUtil.getFieldValue(datum, fieldNames.get(i));
                    row.createCell(i).setCellValue(Convert.convert(String.class, fieldValue));
                }
            }
            String templateFilePath = WordUtils.getTemplateFilePath();
            File file = new File(templateFilePath + "/" + userConfig.getName() + LocalDate.now() + ".xlsx");
            if (file.exists()) {
                file.delete();
            }
            // 将工作簿写入文件
            try (FileOutputStream fileOut = new FileOutputStream(file)) {
                workbook.write(fileOut);
            } catch (IOException e) {
                throw new CustomTableException(e);
            }
            return file;
        }
    }
}
